// 创建一个事件中心对象
class EventEmitter {
  constructor() {
    // 初始化一个空对象存储订阅事件
    this.events = {};
  }
  // 订阅方法
  on(eventName, callback) {
    // 如果已经有该事件名，就将回调函数添加到数组中
    if (this.events[eventName]) {
      this.events[eventName].push(callback);
    } else {
      // 否则就创建一个新的数组并添加回调函数
      this.events[eventName] = [callback];
    }
  }
  // 取消订阅方法
  off(eventName, callback) {
    // 如果有该事件名，就从数组中移除回调函数
    if (this.events[eventName]) {
      this.events[eventName] = this.events[eventName].filter(
        (cb) => cb !== callback
      );
      // 如果数组为空，就删除该事件名
      if (this.events[eventName].length === 0) {
        delete this.events[eventName];
      }
    }
  }
  // 发布方法
  emit(eventName, ...args) {
    // 如果有该事件名，就遍历数组并执行回调函数
    if (this.events[eventName]) {
      this.events[eventName].forEach((cb) => cb(...args));
    }
  }
  // 只发布一次方法
  once(eventName, callback) {
    // 定义一个包装函数，在执行回调函数后取消订阅
    const wrapFunc = (...args) => {
      callback(...args);
      this.off(eventName, wrapFunc);
    };
    // 使用订阅方法添加到列表中
    this.on(eventName, wrapFunc);
  }
}
